package com.qiantu.api.utils;

import android.text.TextUtils;
import android.util.Base64;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class Md5Util {

    public final static String MD5 = "MD5";

    /**
     * 获取指定字符串的MD5值
     *
     * @param info 需要获取MD5值得字符串
     * @return String 生成的MD5值
     */
    public static String getStringMD5(String info) {
        if (info == null) {
            return "";
        }
        StringBuilder strBuf = new StringBuilder();
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            if (digest == null) {
                return strBuf == null ? "" : strBuf.toString();
            }
            digest.update(info.getBytes("UTF-8"));
            byte[] encryption = digest.digest();
            if (encryption == null) {
                return strBuf == null ? "" : strBuf.toString();
            }
            for (int i = 0; i < encryption.length; i++) {
                if (Integer.toHexString(0xff & encryption[i]).length() == 1) {
                    strBuf.append("0").append(Integer.toHexString(0xff & encryption[i]));
                } else {
                    strBuf.append(Integer.toHexString(0xff & encryption[i]));
                }
            }
            return strBuf.toString();
        } catch (NoSuchAlgorithmException e) {
            return strBuf == null ? "" : strBuf.toString();
        } catch (UnsupportedEncodingException e) {
            return strBuf == null ? "" : strBuf.toString();
        } finally {
            return strBuf == null ? "" : strBuf.toString();
        }
    }

    public static String getURLEncoded(String paramString) {
        if (TextUtils.isEmpty(paramString)) {
            return "";
        }
        try {
            String str = new String(paramString.getBytes(), "UTF-8");
            str = URLEncoder.encode(str, "UTF-8");
            return str;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public static String encodedText(String s) {
        return getStringMD5(s + System.currentTimeMillis()) + "A";
    }

    /**
     * 获取指定文件的MD5值
     *
     * @param file 需要获取MD5值的文件
     * @return String 生成的MD5值  计算不正确
     */
    public static String getFileMD5(File file) {
        if (file == null) {
            return null;
        }
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(file);
            if (inputStream == null) {
                return "";
            }
            byte[] buffer = new byte[1024 * 8];
            if (buffer == null) {
                return "";
            }
            MessageDigest digest = MessageDigest.getInstance("MD5");
            int numRead = 0;
            while ((numRead = inputStream.read(buffer)) > 0) {
                digest.update(buffer, 0, numRead);
            }
            return toHexString(digest.digest());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "";
    }

    /**
     * 转换成16进制
     *
     * @param bytes
     * @return
     */
    private static String toHexString(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        StringBuilder hexString = new StringBuilder();
        String hexOfByte;
        for (byte b : bytes) {
            hexOfByte = Integer.toHexString(0xFF & b);
            if (hexOfByte.length() == 1) {
                hexString.append("0").append(hexOfByte);
            } else {
                hexString.append(hexOfByte);
            }
        }
        return hexString.toString();
    }

    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    /**
     * 检查文件的md5特征码
     */
    public static String encodeFile(String apkpath) {
        String md5 = null;
        FileInputStream fis = null;
        try {
            File file = new File(apkpath);
            MessageDigest digest = MessageDigest.getInstance("md5");
            fis = new FileInputStream(file);
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = fis.read(buffer)) != -1) {
                digest.update(buffer, 0, len);
            }
            byte[] result = digest.digest();
            StringBuffer sb = new StringBuffer();
            for (byte b : result) {
                String str = Integer.toHexString(b & 0xff);
                if (str.length() == 1) {
                    sb.append("0");
                }
                sb.append(str);
            }

            md5 = sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null)
                    fis.close();
            } catch (IOException i) {
                i.printStackTrace();
            }
        }
        return md5;
    }

    public static String getMD5ofStr(String plainText) {
        try {
            return getMD5ofStr(string2Bytes(plainText));
        } catch (Exception e) {

        }
        return null;
    }

    public static String getMD5ofStr(byte str[]) {
        try {
            MessageDigest md = MessageDigest.getInstance(MD5);
            md.update(str);
            byte b[] = md.digest();
            return toHexString(b);

        } catch (Exception e) {

        }
        return null;
    }

    public static byte[] string2Bytes(String s) {
        byte[] bytes = null;
        if (s != null) {
            try {
                bytes = s.getBytes("utf-8");
            } catch (UnsupportedEncodingException e) {

            }
        }
        return bytes;
    }

    /**
     * 加密：对字符串进行加密，并返回十六进制字符串(hex)
     *
     * @param encryptStr 需要加密的字符串
     * @return 加密后的十六进制字符串(hex)
     */
    public static String encrypt(String encryptStr, String key, String iv) {
        try {
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("UTF-8"));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);

            byte[] encrypted = cipher.doFinal(encryptStr.getBytes());


//              byte[] encode = Base64Encoder.encode(encrypted);

            String string = Base64Encoder.encode(encrypted);
//            String string = Base64.encodeToString(encrypted, Base64.DEFAULT);
            return string;
            //     return byte2HexStr(encrypted);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return null;
    }

    /**
     * 解密：对加密后的十六进制字符串(hex)进行解密，并返回字符串
     *
     * @param encryptedStr 需要解密的，加密后的十六进制字符串
     * @return 解密后的字符串
     */
    public static String decrypt(String encryptedStr, String key, String iv) {
        try {
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("UTF-8"));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");


            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7PADDING");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec);



//            byte[] decode = Base64Encoder.decode(encryptedStr);
            byte[] decode = Base64.decode(encryptedStr, Base64.DEFAULT);

            //  byte[] bytes = hexStr2Bytes(encryptedStr);
            byte[] original = cipher.doFinal(decode);

            return new String(original);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return null;
    }
}
